#ifndef N0TEMPLATES_H_2006_11_05
#define N0TEMPLATES_H_2006_11_05

#include "N0Defs.h"

template<class T1, class T2>
class N0Tuple {
public:
    union {
        T1 v1;
        T1 first;
    };
    union {
        T2 v2;
        T2 second;
    };
};

template<class T1, class T2, class T3>
class N0Triple {
public:
    union {
        T1 v1;
        T1 first;
    };
    union {
        T2 v2;
        T2 second;
    };
    union {
        T3 v3;
        T3 third;
    };
};

#define N0STATIC_CHECK(condition, message) \
class SC_##message {                       \
    char Error_##message[condition-1];       \
};

#define N0STATIC_CHECK2(condition, message) \
template<bool C>                            \
class SC_##message;                         \
template<>                                  \
class SC_##message<true> {                  \
};

#if GCC_ABOVE(4, 1) || _MSC_VER>1000

#define N0ISCHILDOF(child, parent) (N1IsChildOf<child, parent>::result)

template<class A, class B>
class N0IsChildOf2 {
    class Good { char c[64]; };
    class Bad  { char c[32]; };
public:
    static Bad     test(...);
    static Good    test(B*);
    typedef struct {
       char a[ sizeof( test((A*)0) ) ];
    } resultStruct;
};

template<class A, class B>
class N0IsChildOf : public N0IsChildOf2<A, B> {
public:
    enum { size1 = sizeof(typename N1IsChildOf2<A, B>::resultStruct) };
    enum { size2 = sizeof(typename N1IsChildOf2<A, B>::Bad) };
    enum { result = int(size1-size2) };
};

#endif

#endif //N0TEMPLATES_H_2006_11_05
